﻿using System;
using System.Collections;
using System.Collections.Generic;
using LogSystem;
using UnityEngine;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

namespace Yoozoo.Core.Common
{
    public class LoadingTaskManager : MonoBehaviour
    {
        public static LoadingTaskManager Inst;

        public bool enterSceneSuccess = true;
        public int ResLoadingCount;
        
        public List<SmartResLoader> smartResLoaders;
        public List<LoadConstructTask> constructTasks;

        private Dictionary<string, int> _loaderName2Type;

        private readonly System.Diagnostics.Stopwatch _stopwatch = 
            new System.Diagnostics.Stopwatch();
        
        private int _curConstructIndex = 0;
        
        private void Awake()
        {
            Inst = this;
            smartResLoaders = new List<SmartResLoader>(200);
            constructTasks = new List<LoadConstructTask>(200);

            _loaderName2Type = new Dictionary<string, int>(200);
        }

        public void AddLoaderNameType(string loaderName,int type)
        {
            _loaderName2Type.Add(loaderName,type);
        }

        public SmartResLoader AddLoadTask(string taskName)
        {
            SmartResLoader smartResLoader = new SmartResLoader(taskName);
            smartResLoaders.Add(smartResLoader);
            return smartResLoader;
        }
        
        public SmartResLoader AddLoadTask(string taskName, string resPath,Res.ResLoadCompleteCallBack callback = null)
        {
            SmartResLoader smartResLoader = new SmartResLoader(taskName,resPath, callback);
            smartResLoaders.Add(smartResLoader);
            return smartResLoader;
        }

        public SmartResLoader AddLoadTask(string taskName, List<string> resPaths, Res.ResLoadCompleteCallBack updateCallback = null,
            Action completeCallback = null)
        {
            SmartResLoader smartResLoader = new SmartResLoader(taskName, resPaths, updateCallback,completeCallback);
            smartResLoaders.Add(smartResLoader);
            return smartResLoader;
        }

        public LoadConstructTask AddConstructTask(string taskName,Action action,int type)
        {
            LoadConstructTask constructTask = new LoadConstructTask(taskName, action,type);
            constructTasks.Add(constructTask);
            return constructTask;
        }

        public void OnEnterScene(string sceneName)
        {
            enterSceneSuccess = true;
        }
        

        private void Update()
        {
            _stopwatch.Reset();
            _stopwatch.Start();

            long lastCostTime = 0;
            while (_curConstructIndex < constructTasks.Count && _stopwatch.ElapsedMilliseconds < 30)
            {
                constructTasks[_curConstructIndex].Execute();
                
                Debug.Log(LogModule.Loading,
                    $"constructTaskName: {constructTasks[_curConstructIndex].TaskName},花费时长：{_stopwatch.ElapsedMilliseconds - lastCostTime}ms");
                lastCostTime = _stopwatch.ElapsedMilliseconds;
                
                _curConstructIndex++;
            }
            
            _stopwatch.Stop();
        }


        private void LateUpdate()
        {
            ResLoadingCount = SmartResLoader.ResLoadingCount;
            //Debug.Log(LogModule.Loading,$"当前LoadingResCount：{ResLoadingCount}");
        }

        // 移除构造事件
        public void RemoveConstructTask(string taskName)
        {
            for (int i = _curConstructIndex; i < constructTasks.Count; i++)
            {
                if (constructTasks[i].TaskName == taskName)
                {
                    constructTasks.RemoveAt(i);
                    break;
                }
            }
        }
        
        // 获取当前构建任务的完成状态
        public bool GetConstructTaskState(string taskName)
        {
            foreach (var task in constructTasks)
            {
                if (task.TaskName == taskName)
                {
                    return task.complete;
                }
            }
            return false;
        }
        
        // 测试用
        public void DisposeTask(string taskName)
        {
            foreach (var smartResLoader in smartResLoaders)
            {
                if (smartResLoader.taskName == taskName)
                {
                    smartResLoader.Dispose();
                    smartResLoaders.Remove(smartResLoader);
                    break;
                }
            }
        }

        public void Dispose(bool includeCity = false)
        {
            if (smartResLoaders != null)
            {
                List<SmartResLoader> _cacheLoaders = new List<SmartResLoader>(40);
                foreach (var resLoader in smartResLoaders)
                {
                    if (resLoader!=null)
                    {
                        if (_loaderName2Type.TryGetValue(resLoader.taskName,out int type))
                        {
                            if ((type == 1 || type == 3) && !includeCity)  // 现在不卸载内城的Loader
                            {
                                _cacheLoaders.Add(resLoader);
                                continue;
                            }
                        }
                        
                        resLoader.Dispose();
                    }
                }
                smartResLoaders.Clear();
                smartResLoaders.AddRange(_cacheLoaders);
            }

            for (int i = constructTasks.Count - 1 ; i >= 0 ; i--)
            {
                if (i < _curConstructIndex)
                {
                    constructTasks.RemoveAt(i);
                }
                else
                {
                    if ((constructTasks[i].Type != 1) && !includeCity) // 内城的延迟加载任务不自动清理，自行控制
                    {
                        constructTasks.RemoveAt(i);
                    }
                }
            }
            
            if (constructTasks!=null)
            {
                constructTasks.Clear();
            }

            _curConstructIndex = 0;
        }

        // 测试用
        public void DisposeAll()
        {
            if (smartResLoaders != null)
            {
                foreach (var resLoader in smartResLoaders)
                {
                    resLoader?.Dispose();
                }
                smartResLoaders.Clear();
            }

            constructTasks?.Clear();

            _curConstructIndex = 0;
        }

    }
}
